﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.Remoting.Channels;
using System.Threading;
using DataManage.Data;
using ServiceLayerManagement;

namespace DataManage
{
    public class GlobalData
    {
        #region 应用程序地址
        /// <summary>
        /// 公共存储库路径
        /// </summary>
        private static string AppFoloderPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "/EVEBMS";
        /// <summary>
        /// CAN配置文件路径
        /// </summary>
        private static string CANConfigPath = $"{AppFoloderPath}/CANConfig.cfg";
        /// <summary>
        /// 数据帧点表文件路径
        /// </summary>
        private static string DataFramePointTablePath = $"{AppFoloderPath}/DataFramePointTableConfig.cfg";
        /// <summary>
        /// 故障信息路径
        /// </summary>
        private static string FaultInfoPath = $"{AppFoloderPath}/FaultInfoConfig.cfg";
        /// <summary>
        /// 上位机登录配置文件路径
        /// </summary>
        private static string PCLoginConfigPath = $"{AppFoloderPath}/PCLoginConfigPath.cfg";
        #endregion

        public static ConcurrentQueue<DataFrames> ReceviedData; //接收的数据帧
        public static PlatformConfig PlatformConfig;//can参数配置
        /// <summary>
        /// 设备指针
        /// </summary>
        public static IntPtr Device_Handle;
        /// <summary>
        /// 通道指针
        /// </summary>
        public static IntPtr Channel_Handle;

        #region CAN设备关闭委托
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate UInt32 DeviceClosedEventHandler(IntPtr device_Handle);
        public static DeviceClosedEventHandler OnDeviceClosedEvent;//方法调用
        public static event DeviceClosedEventHandler DeviceClosed//委托方法绑定
        {
            add { OnDeviceClosedEvent += new DeviceClosedEventHandler(value); }
            remove { OnDeviceClosedEvent -= new DeviceClosedEventHandler(value); }
        }
        #endregion

        private static bool canConnectState;
        /// <summary>
        /// CAN通道链接状态
        /// </summary>
        public static bool CANConnectState { get => canConnectState; set { canConnectState = value; ReceivedDataQueueResetManualState(); } }

        /// <summary>
        /// 接收队列处理线程
        /// </summary>
        public static ManualResetEvent ReceivedDataQueueResetManual = new ManualResetEvent(false);
        /// <summary>
        /// 程序启动线程处理
        /// </summary>
        public static ManualResetEvent MainThreadResetEvent = new ManualResetEvent(false);
        /// <summary>
        /// 当前所选页
        /// </summary>
        public static PageType CurrentPageType;
        public static List<DataFramePointTable> FramePointTable;
        public static CustomResourceCollection FaultInfo;
        public static PCLoginConfig PCLoginConfig;

        //待删
        public static int handleCount = 0;

        /// <summary>
        /// 程序开始
        /// </summary>
        public static void AppStart()
        {
            try
            {
                Init();
                GetPlatformConfig();
                GetDataFramePointTable();
                GetFaultInfo();
                GetPCLoginConfig();
            }
            catch(Exception ex)
            {
                throw new Exception(ex.Message);
            }
           
        }
        /// <summary>
        /// 程序关闭
        /// </summary>
        public static void AppStop()
        {
            try
            {
                MainThreadResetEvent.Reset();
                SetPlatformConfig();
                if(OnDeviceClosedEvent != null)
                {
                    OnDeviceClosedEvent(Device_Handle);
                    DeviceClosed -= OnDeviceClosedEvent;
                }
                SetDataFramePointTable();
                SetFaultInfo();
                SetPCLoginConfig();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        /// <summary>
        /// 初始化
        /// </summary>
        public static void Init()
        {
            MainThreadResetEvent.Set();

            if (!Directory.Exists(AppFoloderPath)) Directory.CreateDirectory(AppFoloderPath);

            if (ReceviedData == null) ReceviedData = new ConcurrentQueue<DataFrames>();
        }
        /// <summary>
        /// 初始化can配置
        /// </summary>
        public static void GetPlatformConfig()
        {
            bool result = true;
            if (!File.Exists(CANConfigPath))
            {
                result = false;
            }
            else
            {
                PlatformConfig = BinaryFormatterHelper.LoadFileByBinary<PlatformConfig>(CANConfigPath);

                if(PlatformConfig == null) result = false;
            }
            if (!result)
            {
                PlatformConfig = new PlatformConfig()
                {
                    CANCompany = CANSupplierType.ZLG,
                    CANType = ZLGCANType.USBCANFD_200U,
                    CANIndex = 0,
                    CANChannel = 0,
                    BautRate = "250kbps",
                };
                SetPlatformConfig();
            }
           
        }
        /// <summary>
        /// 保存can配置
        /// </summary>
        public static void SetPlatformConfig()
        {
            BinaryFormatterHelper.SaveFileByBinary<PlatformConfig>(CANConfigPath, PlatformConfig);
        }
        /// <summary>
        /// 消费线程队列阻塞状态
        /// </summary>
        private static void ReceivedDataQueueResetManualState()
        {
            if(CANConnectState)
            {
                ReceivedDataQueueResetManual.Set();
            }
            else
            {
                ReceivedDataQueueResetManual.Reset();
                ReceivedQueueClear();
            }
        }
        /// <summary>
        /// 丢弃消费线程数据
        /// </summary>
        private static void ReceivedQueueClear()
        {
            while (ReceviedData?.Count > 0)
            {
                ReceviedData.TryDequeue(out _);
            }
        }

        private static void GetDataFramePointTable()
        {
            bool result = true;
            if (!File.Exists(DataFramePointTablePath))
            {
                result = false;
            }
            else
            {
                FramePointTable = BinaryFormatterHelper.LoadFileByBinary<List<DataFramePointTable>>(DataFramePointTablePath);
                if (FramePointTable == null || FramePointTable?.Count <= 0) result = false;
            }

            if (!result)
            {
                FramePointTable = new List<DataFramePointTable>();
                SetDataFramePointTable();
            }
        }

        public static void SetDataFramePointTable()
        {
            BinaryFormatterHelper.SaveFileByBinary<List<DataFramePointTable>>(DataFramePointTablePath, FramePointTable);
        }

        private static void GetFaultInfo()
        {
            bool result = true;
            if (!File.Exists(FaultInfoPath))
            {
                result = false;
            }
            else
            {
                FaultInfo = BinaryFormatterHelper.LoadFileByBinary<CustomResourceCollection>(FaultInfoPath);
                if (PCLoginConfig == null || FaultInfo.CustomResources == null || FaultInfo.CustomResources.Count <= 0) result = false;
            }

            if (!result)
            {
                FaultInfo = new CustomResourceCollection();
                SetFaultInfo();
            }
        }

        public static void SetFaultInfo()
        {
            BinaryFormatterHelper.SaveFileByBinary<CustomResourceCollection>(FaultInfoPath, FaultInfo);
        }
        private static void GetPCLoginConfig()
        {
            
            //bool result = true;
            //if (!File.Exists(PCLoginConfigPath))
            //{
            //    result = false;
            //}
            //else
            //{
            //    PCLoginConfig = BinaryFormatterHelper.LoadFileByBinary<PCLoginConfig>(PCLoginConfigPath);
            //    if (PCLoginConfig == null) result = false;
            //}

            //if (!result)
            //{
            //    PCLoginConfig = new PCLoginConfig();
            //    SetPCLoginConfig();
            //}
        }

        public static void SetPCLoginConfig()
        {
            //BinaryFormatterHelper.SaveFileByBinary<PCLoginConfig>(PCLoginConfigPath, PCLoginConfig);
        }
    }
}